﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace NumberPuzzle
{
    public partial class BoardNumber : UserControl
    {
        private Button[,] piece;
        private int rowEmpty;
        private int colEmpty;
        private int[,] puzzle;
        public BoardNumber()
        {
            InitializeComponent();
            piece = new Button[4, 4];
            puzzle = new int[piece.GetLength(0), piece.GetLength(1)];
            int number = 1;
            int sizeX = this.Width / piece.GetLength(0);
            int sizeY = this.Height / piece.GetLength(1);
            for (int i = 0; i < piece.GetLength(0); i++)
            {
                for (int j = 0; j < piece.GetLength(1); j++)
                {
                    piece[i, j] = new Button();
                    piece[i, j].Text = number.ToString();
                    piece[i, j].Size = new Size(sizeX, sizeY);
                    piece[i, j].Location = new Point(j * sizeX, i * sizeY);
                    piece[i, j].Tag = new Point(i, j);
                    piece[i, j].Font = new Font("Microsoft Sans Serif", 20F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)));
                    piece[i, j].Click += new EventHandler(BoardNumber_Click);
                    if (number % 2 == 0)
                    {
                        piece[i, j].ForeColor = Color.Blue;
                        piece[i, j].BackColor = Color.White;
                    }
                    else
                    {
                        piece[i, j].ForeColor = Color.White;
                        piece[i, j].BackColor = Color.Brown;
                    }
                    if (number == piece.GetLength(0) * piece.GetLength(1))
                    {
                        piece[i, j].Visible = false;
                    }
                    this.Controls.Add(piece[i, j]);
                    puzzle[i, j] = number;
                    number++;
                }
            }
            rowEmpty = piece.GetLength(0) - 1;
            colEmpty = piece.GetLength(1) - 1;
        }

        private void BoardNumber_Click(object sender, EventArgs e)
        {
            int row = ((Point)((Button)sender).Tag).X;
            int col = ((Point)((Button)sender).Tag).Y;
            MovePiece(row, col);
        }

        private bool ExistsPiece(int row, int col)
        {
            return (row >= 0 && row < piece.GetLength(0) && col >= 0 && col < piece.GetLength(1));
        }

        private bool CanMovePiece(int row, int col)
        {
            int width = piece[0, 0].Width;
            int height = piece[0, 0].Height;
            return piece[rowEmpty, colEmpty].Location.X - piece[row, col].Location.X == 0 &&
                   piece[rowEmpty, colEmpty].Location.Y - piece[row, col].Location.Y == height
                || piece[rowEmpty, colEmpty].Location.X - piece[row, col].Location.X == width &&
                   piece[rowEmpty, colEmpty].Location.Y - piece[row, col].Location.Y == 0
                || piece[row, col].Location.X - piece[rowEmpty, colEmpty].Location.X == 0 &&
                   piece[row, col].Location.Y - piece[rowEmpty, colEmpty].Location.Y == height
                || piece[row, col].Location.X - piece[rowEmpty, colEmpty].Location.X == width &&
                   piece[row, col].Location.Y - piece[rowEmpty, colEmpty].Location.Y == 0;

        }

        private bool Resolved()
        {
            bool IsOk = true;
            for (int i = 0; i < piece.GetLength(0); i++)
            {
                for (int j = 0; j < piece.GetLength(1); j++)
                {
                    IsOk = puzzle[i, j].ToString() == piece[i, j].Text;
                    if (!IsOk) break;
                }
                if (!IsOk) break;
            }

            return IsOk;
        }

        public void MovePiece(int row, int col)
        {
            if (ExistsPiece(row, col) && CanMovePiece(row, col))
            {
                piece[rowEmpty, colEmpty].Visible = true;
                piece[row, col].Visible = false;

                string sAux = piece[rowEmpty, colEmpty].Text;
                piece[rowEmpty, colEmpty].Text = piece[row, col].Text;
                piece[row, col].Text = sAux;

                Color colAux = piece[rowEmpty, colEmpty].BackColor;
                piece[rowEmpty, colEmpty].BackColor = piece[row, col].BackColor;
                piece[row, col].BackColor = colAux;

                colAux = piece[rowEmpty, colEmpty].ForeColor;
                piece[rowEmpty, colEmpty].ForeColor = piece[row, col].ForeColor;
                piece[row, col].ForeColor = colAux;

                rowEmpty = row;
                colEmpty = col;

                if (Resolved())
                    MessageBox.Show("Puzzle Resuelto");
            }
        }

        public void Initialize(int[,] puzzle)
        {
            for (int i = 0; i < piece.GetLength(0); i++)
            {
                for (int j = 0; j < piece.GetLength(1); j++)
                {
                    this.puzzle[i, j] = puzzle[i, j];
                    piece[i, j].Text = puzzle[i, j].ToString();
                }
            }
        }
    }
}
